package com.lpb.spring.lpbspring.getway.util;



import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class DateUtils extends org.apache.commons.lang3.time.DateUtils {

    private static final ConcurrentMap<String, DateTimeFormatter> FORMATTER_CACHE = new ConcurrentHashMap<>();

    private static final int PATTERN_CACHE_SIZE = 500;

    public static String nowDate() {
        return LocalDate.now().toString();
    }

    public static String nowTime() {
        return LocalTime.now().toString();
    }

    public static String nowDateTime() {
        DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder();
        return LocalDateTime.now().format(createCacheFormatter("yyyy-MM-dd HH:mm:ss"));
    }

    public static void main(String[] args) {
        System.out.println(getPrevDateHour("2023030319"));
    }

    private static Integer getPrevDateHour(String currentDateHour) {
        String currentDateTimeStr = currentDateHour + "0000";
        Date currentDateTime = parseDatetime(currentDateTimeStr, "yyyyMMddHHmmss");
        Date prevDateTimeStr = DateUtils.addHours(currentDateTime, -1);
        return Integer.parseInt(format(prevDateTimeStr, "yyyyMMddHHmmss").substring(0, 10));
    }

    public static String format(Date date, String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        LocalDateTime dateTime = LocalDateTime.of(
                calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH) + 1,
                calendar.get(Calendar.DAY_OF_MONTH),
                calendar.get(Calendar.HOUR_OF_DAY),
                calendar.get(Calendar.MINUTE),
                calendar.get(Calendar.SECOND),
                calendar.get(Calendar.MILLISECOND)
        );
        return dateTime.format(createCacheFormatter(format));
    }

    public static Date parse(String dateStr, String pattern) {
        return Date.from(LocalDate.parse(dateStr, createCacheFormatter(pattern)).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parse(String dateStr) {
        return Date.from(LocalDate.parse(dateStr).atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parseDatetime(String dateStr, String pattern) {
        return Date.from(LocalDateTime.parse(dateStr, createCacheFormatter(pattern)).atZone(ZoneId.systemDefault()).toInstant());
    }

    public static Date parseDatetime(String datetimeStr) {
        return Date.from(LocalDateTime.parse(datetimeStr).atZone(ZoneId.systemDefault()).toInstant());
    }





    public static boolean between(Date self, Date one, Date two) {
        long selfTime = self.getTime();
        return selfTime >= one.getTime() && selfTime <= two.getTime();
    }

    private static DateTimeFormatter createCacheFormatter(String pattern){
        if (pattern == null || pattern.length() == 0) {
            throw new IllegalArgumentException("Invalid pattern specification");
        }
        DateTimeFormatter formatter = FORMATTER_CACHE.get(pattern);
        if(formatter == null){
            if(FORMATTER_CACHE.size() < PATTERN_CACHE_SIZE){
                formatter = DateTimeFormatter.ofPattern(pattern);
                DateTimeFormatter oldFormatter = FORMATTER_CACHE.putIfAbsent(pattern, formatter);
                if(oldFormatter != null){
                    formatter = oldFormatter;
                }
            }
        }

        return formatter;
    }
}
